﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading;

namespace Array
{
    class Program
    {
        static void Main(string[] args)
        {
            bool exitFlag = false;
            while(!exitFlag)
            {
            SortType sortType = (SortType) AskSortType();
            int arrayLenght = AskArrayLenght();
            int [] locArray = AskArrayType(arrayLenght);
            Console.WriteLine("Желаете ли вы посмотреть процесс сортирвки: <y/n>?");
            bool draw = AskToDraw();
            if (!draw)
            {
                Console.Clear();
                ChooseArrayTypeForDrawing(sortType , locArray);
           

                // вызов отрисовки

            }
            else
            {
                TimeSpan workSpan = Count(sortType, locArray);
                Console.WriteLine("Время работы метода в милесекундах составило: {0} ", workSpan.TotalMilliseconds);
            }

            Console.WriteLine("Желаете продолжить: <y/n>?");
            exitFlag = AskForExit();
            Console.WriteLine();
    
            }
        }
        public static void DrawArrayMOD(int[] locArray,int MIN,int MAX)
        {
            int yMin = MIN;
            int yMax = MAX;
            int xMax = locArray.Length;
            int j = 0;
            for (int i = 0; i <= yMax; i++)
            {
                if (locArray[j] == i)
                {
                    Console.SetCursorPosition(j, yMax - locArray[j]);
                    Console.Write(".");
                    j++;
                    i = 0;
                }
                if (j == locArray.Length)
                    break;
            }
        }
        public static bool AskForExit()
        {
            bool exitFlag = true;
            char exit = ' ';
            bool inputIsCorrect = false;
            while (!inputIsCorrect)
            {
                try
                {
                     exit = Char.Parse(Console.ReadLine());
                    if (exit == 'y' || exit == 'n')
                    inputIsCorrect = true;
                    else 
                        throw new ArgumentException(); 
                }
                catch
                {
                    Console.WriteLine("Неправильный ввод");
                    Console.WriteLine("Желаете продолжить: <y/n>?");
                }
            }
            if (exit == 'y')
                exitFlag = false;
            else
                exitFlag = true;
            return exitFlag;
        }
        public static bool AskToDraw()
        {
            bool exitFlag = true;
            char exit = ' ';
            bool inputIsCorrect = false;
            while (!inputIsCorrect)
            {
                try
                {
                    exit = Char.Parse(Console.ReadLine());
                    if (exit == 'y' || exit == 'n')
                        inputIsCorrect = true;
                    else
                        throw new ArgumentException();
                }
                catch
                {
                    Console.WriteLine("Неправильный ввод");
                    Console.WriteLine("Желаете ли вы посмотреть процесс сортирвки: <y/n>?");
                }
            }
            if (exit == 'y')
                exitFlag = false;
            else
                exitFlag = true;
            return exitFlag;
        }
        public static int AskSortType()
        {
            Console.WriteLine("Выберите метод сортироки:");
            Console.WriteLine("1 - Сортировка пузырьком");
            Console.WriteLine("2 - Сортировка выбором");
            Console.WriteLine("3 - Сортировка Шелла");
            Console.WriteLine("4 - Сортировка методом Шейкера");
            int sortType = ReadIntFromConsole();
          // if (sortType != 1 ||sortType != 2 ||sortType != 3 ||sortType != 4)
          //      Console.WriteLine ("Неверный ввод");
            return sortType;
        }
        public static int AskArrayLenght()
        {

            Console.WriteLine("Введите желаемую длину массива:");
            int arrayLenght = ReadIntFromConsole();
            return arrayLenght ;
        }
        public static int[] AskArrayType(int arrayLenght)
        {

            Console.WriteLine("какой тип массива вы хотите использовать:");
            Console.WriteLine("1 - Заполненный произвольно");
            Console.WriteLine("2 - Отсортированный по возростаню");
            Console.WriteLine("3 - Отсортированный по убыванию");
            int[] locArray = { };
            int arrayType = ReadIntFromConsole();
            switch (arrayType)
            {
                case 1:
                    locArray = CreateRandomIntArray(arrayLenght);
                    break;
                case 2:
                    locArray = CreateIntArray(arrayLenght);
                    break;
                case 3:
                    locArray = CreateReverseIntArray(arrayLenght);
                    break;
            }
            return locArray;
        }
        public static TimeSpan Count(SortType  sortType, int[] locArray)
        {
            DateTime start = DateTime.Now;
            DateTime currentDate = new DateTime(); ;
            TimeSpan span = new TimeSpan();
            int length1 = locArray.Length;
            switch (sortType)
            {
                case SortType.Bubble :
                    BubbleSort(locArray);
                    currentDate = DateTime.Now;
                    span = currentDate - start;
                    break;
                case SortType.Selection :

                    SelectionSort(locArray);
                    currentDate = DateTime.Now;
                    span = currentDate - start;
                    break;
                case SortType.Shell :
                    ShellSort(locArray);
                    currentDate = DateTime.Now;
                    span = currentDate - start;
                    break;
                case SortType.Shayker :
                    ShaykerSort(locArray);
                    currentDate = DateTime.Now;
                    span = currentDate - start;
                    break;
            }
            return span;
        }
        public static void ChooseArrayTypeForDrawing(SortType  sortType, int[] locArray)
        {
            int length = locArray.Length;
            int MAX = locArray[0], MIN = locArray[0];
            for (int i = 0; i < length; i++)
            {
                if (MIN > locArray[i])
                    MIN = locArray[i];
                if (MAX < locArray[i])
                    MAX = locArray[i];
            }
            switch (sortType)
            {
                case SortType.Bubble :
                    Console.SetWindowPosition(0, 0);
                    Console.SetWindowSize(Console.LargestWindowWidth , Console.LargestWindowHeight);

                    BubbleSort(locArray,MIN,MAX);
                  Console.SetCursorPosition(0, MAX);
                    Console.WriteLine("Массив отсортирован, консоль будет очищена через 5 секунд");
                    Thread.Sleep(5000);
                     Console.Clear();
                    break;
                case SortType.Selection :
                    Console.SetWindowPosition(0, 0);
                    Console.SetWindowSize(Console.LargestWindowWidth, Console.LargestWindowHeight);
                    SelectionSort(locArray, MIN, MAX);
                  Console.SetCursorPosition(0, MAX);
                    Console.WriteLine("Массив отсортирован, консоль будет очищена через 5 секунд");
                    Thread.Sleep(5000);
                     Console.Clear();
                    break;
                case SortType.Shell :
                    Console.SetWindowPosition(0, 0);
                    Console.SetWindowSize(Console.LargestWindowWidth, Console.LargestWindowHeight);
                    ShellSort(locArray, MIN, MAX);
                      Console.SetCursorPosition(0, MAX);
                    Console.WriteLine("Массив отсортирован, консоль будет очищена через 5 секунд");
                    Thread.Sleep(5000);
                     Console.Clear();
                    break;
                case SortType.Shayker :
                    Console.SetWindowPosition(0, 0);
                    Console.SetWindowSize(Console.LargestWindowWidth, Console.LargestWindowHeight);
                    ShaykerSort(locArray, MIN, MAX);
                    Console.SetCursorPosition(0, MAX);
                    Console.WriteLine("Массив отсортирован, консоль будет очищена через 5 секунд");
                    Thread.Sleep(5000);
                     Console.Clear();
                    break;
            }
        }
        public static int ReadIntFromConsole()
        {
            int retVal = 0;
            bool inputIsCorrect = false;
            while (!inputIsCorrect)
            {
                try
                {
                    retVal = Int32.Parse(Console.ReadLine());
                    inputIsCorrect = true;
                    if (retVal <= 0)
                    {
                        throw new ArgumentException();
                    }
                }
                catch
                {
                    Console.WriteLine("Неправильный ввод");
                    Console.WriteLine("Повторите ввод");
                }
            }
            return retVal;
        }
        public static void PrintIntArray(int[] locArray)
        {
            int length = locArray.Length;
            for (int i = 0; i < length; i++)
            {
                Console.Write(locArray[i] + "  ");
            }
        }
        public static int[] CreateIntArray(int number)
        {
            int[] locArray = new int[number];
            for (int i = 0; i < number; i++)
            {
                locArray[i] = i + 1;
            }
            return locArray;
        }
        public static int[] CreateReverseIntArray(int number)
        {
            int[] locArray = new int[number];
            int j = 0;
            for (int i = number; i > 0; i--)
            {
                locArray[j] = number;
                number--;
                j++;
            }
            return locArray;
        }
        public static int[] CreateRandomIntArray(int number)
        {
            int[] locArray = new int[number];
            Random rand = new Random();
            for (int i = 0; i < number; i++)
            {
                locArray[i] = rand.Next(0, 50);
            }
            return locArray;
        }
        public static void BubbleSort(int[] locArray)
        {
           
            for (int i = 0; i < locArray.Length; i++)
                for (int j = 0; j < locArray.Length - 1; j++)
                {   
                    if (locArray[j] > locArray[j + 1])
                    {
                        int tmp = locArray[j];
                        locArray[j] = locArray[j + 1];
                        locArray[j + 1] = tmp;
                    }
                }
        }
        public static void BubbleSort(int[] locArray,int MIN,int MAX)
        {

            for (int i = 0; i < locArray.Length; i++)
                for (int j = 0; j < locArray.Length - 1; j++)
                {
                    if (locArray[j] > locArray[j + 1])
                    {
                        int tmp = locArray[j];
                        locArray[j] = locArray[j + 1];
                        locArray[j + 1] = tmp;
                        Console.Clear();
                        DrawArrayMOD(locArray, MIN, MAX);
                        Thread.Sleep(2);
                    }
                }
           
            DrawArrayMOD(locArray, MIN, MAX);
            Thread.Sleep(2);
        }
        public static void SelectionSort(int[] locArray)
        {
            for (int i = 0; i < locArray.Length; i++)
            {
                int min = i; int x = locArray[i];
                for (int j = i + 1; j < locArray.Length; j++)
                {
                    if (locArray[j] < x)
                    {
                        min = j; x = locArray[j];
                    }        
                }
                locArray[min] = locArray[i];
                locArray[i] = x;
              }
        }
        public static void SelectionSort(int[] locArray, int MIN, int MAX)
        {
            for (int i = 0; i < locArray.Length; i++)
            {
                int min = i; int x = locArray[i];
                for (int j = i + 1; j < locArray.Length; j++)
                {
                    if (locArray[j] < x)
                    {
                        min = j; x = locArray[j];
                        Console.Clear();
                        DrawArrayMOD(locArray, MIN, MAX);
                        Thread.Sleep(2);
                    }
                }
                locArray[min] = locArray[i];
                locArray[i] = x;
                Console.Clear();
                DrawArrayMOD(locArray, MIN, MAX);
                Thread.Sleep(2);
            }
        }
        public static void ShellSort(int[] locArray)
          {
            
             int step = locArray.Length / 2;
             Console.WriteLine();
             while (step > 0)
            {
                for (int i = 0; i < (locArray.Length - step); i++)
                {
                    int j = i;
                    while ((j >= 0) && (locArray[j] > locArray[j + step]))
                    {
                        int tmp = locArray[j];
                        locArray[j] = locArray[j + step];
                        locArray[j + step] = tmp;
                        j--;
                    }   
                }
                step = step / 2;
            }
         }
        public static void ShellSort(int[] locArray ,int MIN, int MAX)
        {

            int step = locArray.Length / 2;
            Console.WriteLine();
            while (step > 0)
            {
                for (int i = 0; i < (locArray.Length - step); i++)
                {
                    int j = i;
                    while ((j >= 0) && (locArray[j] > locArray[j + step]))
                    {
                        int tmp = locArray[j];
                        locArray[j] = locArray[j + step];
                        locArray[j + step] = tmp;
                        Console.Clear();
                        DrawArrayMOD(locArray, MIN, MAX);
                        Thread.Sleep(30);
                        j--;
                    }
                }
                step = step / 2;
            }
            Console.Clear();
            DrawArrayMOD(locArray, MIN, MAX);
            Thread.Sleep(30);
        }
        public static void ShaykerSort(int[] locArray)
          {
              int l2 = 1, r2 = locArray.Length - 1;
              int k2 = locArray.Length - 1, tmp2;
            do
            {
                for (int i = r2; i > 0; i--)
                {
                    if (locArray[i - 1] > locArray[i])
                    {
                        tmp2 = locArray[i - 1];
                        locArray[i - 1] = locArray[i];
                        locArray[i] = tmp2;
                        k2 = i;

                    }
                }
                l2 = k2 + 1;
                for (int i = 1; i <= r2; i++)
                {
                    if (locArray[i - 1] > locArray[i])
                    {
                        tmp2 = locArray[i - 1];
                        locArray[i - 1] = locArray[i];
                        locArray[i] = tmp2;
                        k2 = i;
                    }
                }
                r2 = k2 - 1;

            }
            while (l2 < r2);
       }
        public static void ShaykerSort(int[] locArray, int MIN, int MAX)
        {
            int l2 = 1, r2 = locArray.Length - 1;
            int k2 = locArray.Length - 1, tmp2;
            do
            {
                for (int i = r2; i > 0; i--)
                {
                    if (locArray[i - 1] > locArray[i])
                    {
                        tmp2 = locArray[i - 1];
                        locArray[i - 1] = locArray[i];
                        locArray[i] = tmp2;
                        k2 = i;
                        Console.Clear();
                        DrawArrayMOD(locArray, MIN, MAX);
                        Thread.Sleep(30);
                    }
                }
                l2 = k2 + 1;
                for (int i = 1; i <= r2; i++)
                {
                    if (locArray[i - 1] > locArray[i])
                    {
                        tmp2 = locArray[i - 1];
                        locArray[i - 1] = locArray[i];
                        locArray[i] = tmp2;
                        k2 = i;
                        Console.Clear();
                        DrawArrayMOD(locArray, MIN, MAX);
                        Thread.Sleep(30);
                    }
                }
                r2 = k2 - 1;

            }
            while (l2 < r2);
            Console.Clear();
            DrawArrayMOD(locArray, MIN, MAX);
            Thread.Sleep(30);
        }
        public enum SortType 
        { 
            Bubble = 1,
            Selection = 2 ,
            Shell = 3,
            Shayker = 4
        };
    }


















    

}
